const { mappedPortTable, mappingPorts, connections } = require('../../utils/cache')
const util = require('util')
const hx = require('hbuilderx')
const { forward } = require('../../utils/mapping-port')

async function onEnable(data) {
    const client = connections.get(this.options.host)
    const key = util.format('%s-%s', this.options.host, data.clientPort)
    const item = mappingPorts.get(key)
    if (item) {
        const msg = util.format('本地客户端已经转发到 %s->%s', item.data.host, item.data.serverPort)
        throw new Error(msg)
    }
    await forward(client.connection, data)
}

async function onDisable(data) {
    const key = util.format('%s-%s', this.options.host, data.clientPort)
    const item = mappingPorts.get(key)
    if (item) {
        item.child.kill('SIGINT')
        mappingPorts.delete(key)
    }
    data.notConnected = true
    await mappedPortTable.save(data)
}

async function onDirectionChange(data) {
    let tip
    data.isIn = !data.isIn
    if (data.isIn) {
        tip = util.format(
            '确认将服务器端口[%s]转发到本地端口[%s]吗?',
            data.serverPort,
            data.clientPort
        )
    } else {
        tip = util.format(
            '确认将本地端口[%s]转发到服务器端口[%s]吗?',
            data.clientPort,
            data.serverPort
        )
    }
    const button = await hx.window.showMessageBox({
        type: 'question',
        title: '转发方向变更',
        text: tip,
        buttons: ['确认', '取消']
    })
    if (button == '确认') {
        await onDisable.call(this, data)
        await onEnable.call(this, data)
    }
}

async function onRemove(data) {
    const button = await hx.window.showMessageBox({
        type: 'question',
        title: '删除',
        text: '确认删除此端口映射吗?',
        buttons: ['确认', '取消']
    })
    if (button == '确认') {
        await onDisable.call(this, data)
        data.host = this.options.host
        await mappedPortTable.remove(data)
    }
}

async function onInit() {
    const mappings = await mappedPortTable.data(this.options.host)
    mappings ||= []
    mappings.forEach(it => {
        const key = util.format('%s-%s', it.host, it.clientPort)
        it.notConnected = !mappingPorts.has(key)
    })

    if (mappings.length == 0) {
        mappings.push({
            clientPort: '',
            serverPort: '',
            isIn: false,
            notConnected: true
        })
    }
    return mappings
}

module.exports = {
    onRemove,
    onInit,
    onDisable,
    onEnable,
    onDirectionChange
}
